package com.xhorse.lockplatform.interceptor;

import com.xhorse.lockplatform.annotation.RequestLimit;
import com.xhorse.lockplatform.comm.enums.ResultEnum;
import com.xhorse.lockplatform.comm.exception.LockPlatFormException;
import com.xhorse.lockplatform.comm.util.LogUtil;
import com.xhorse.lockplatform.comm.util.RequestUtils;
import com.xhorse.lockplatform.service.base.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;

public class FrequencyLimitInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisService redisService;

    @Value("${com.items.validation}")
    private boolean validation;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        if (!validation) {
            //若开关关闭，则直接跳过次数限制
            return true;
        }
        //获取方法上注解
        RequestLimit limit = ((HandlerMethod) handler).getMethodAnnotation(RequestLimit.class);
        if (limit != null) {
            if (request == null) {
                throw new LockPlatFormException(ResultEnum.FAILED.getCode(), "方法中缺失HttpServletRequest参数");
            }
            String ip = RequestUtils.getRemoteIp(request);
            String url = request.getRequestURL().toString();
            String key = "req_limit_".concat(url).concat(ip);
            // 设置在redis中的缓存，累加1
            int count = redisService.incrementFun(key, 1);
            if (count == 1) {
                redisService.set(key, count, limit.time());
            }
            // 如果redis中的count大于限制次数，则报错
            if (count > limit.count()) {
                String result = "-4";
                OutputStream ops = response.getOutputStream();
                byte[] dataByteArr = result.getBytes("UTF-8");
                ops.write(dataByteArr);
                return false;
            }
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

    }

}
